import { Editor, Transforms } from 'slate';
import { EDITOR_ELEMENT_TYPE, PLUGINS_KEYS, Plugin, commandType } from '../types';
import { isCollapsed, isMatchKeyDown } from '@/core/utils/is';
import { KEYDOWNS } from '@/core/types';
import { getBlockMatch } from '@/core/utils/get';

const SHORTCUTS: Record<string, string> = {
  '#': `${PLUGINS_KEYS.HEADING}.h1`,
  '##': `${PLUGINS_KEYS.HEADING}.h2`,
  '###': `${PLUGINS_KEYS.HEADING}.h3`,
  '####': `${PLUGINS_KEYS.HEADING}.h4`,
  '#####': `${PLUGINS_KEYS.HEADING}.h5`,
  '######': `${PLUGINS_KEYS.HEADING}.h6`,
  '-': PLUGINS_KEYS.UNORDEREDLIST,
  '>': PLUGINS_KEYS.QUOTELIST,
};

const TRANSFORMS = {
  [`${PLUGINS_KEYS.HEADING}.h1`]: { level: 1 },
  [`${PLUGINS_KEYS.HEADING}.h2`]: { level: 2 },
  [`${PLUGINS_KEYS.HEADING}.h3`]: { level: 3 },
  [`${PLUGINS_KEYS.HEADING}.h4`]: { level: 4 },
  [`${PLUGINS_KEYS.HEADING}.h5`]: { level: 5 },
  [`${PLUGINS_KEYS.HEADING}.h6`]: { level: 6 },
};

/**
 * 自定义插件 - 用于实现Markdown快捷语法 或者 其他通用功能
 * @param editor
 */
function Shortcut(editor: Editor, commands: Record<string, commandType>): Plugin {
  return {
    key: PLUGINS_KEYS.SHORTCUT,
    type: EDITOR_ELEMENT_TYPE.BLOCK,
    priority: 50, // 目前是最高的优先级了
    match: () => true,
    render: (context) => context.children,
    onKeyDown: (event) => {
      if (isMatchKeyDown(event, KEYDOWNS.SPACE) && isCollapsed(editor) && editor.selection) {
        const { path } = getBlockMatch(editor);
        const start = Editor.start(editor, path);
        const range = { anchor: editor.selection.anchor, focus: start };
        const beforeText = Editor.string(editor, range);
        const type = SHORTCUTS[beforeText];
        if (!type) return;
        event.preventDefault();
        Transforms.select(editor, range);
        Transforms.delete(editor);
        /**
         * 下面的思路是调用匹配上的Plugin的command
         */
        const key = type.split('.')[0];
        commands[key] && commands[key](editor, key, TRANSFORMS[type] || {}, path);
      }
      return null;
    },
  };
}

export default Shortcut;
